import { Asset, assetManager, AssetManager, sys } from "cc";
import { HttpRequest } from "./network/HttpRequest";
import Singleton from "./Singleton";

interface BundleConfig {
    remote: string;
    bundles: Record<string, string>;
}

export class bundleTool extends Singleton{
	private _bundlesCfs:BundleConfig = null;
	loadConfig(url){
		return new Promise<boolean>((resolve, reject) => {
			if(sys.isNative&& !this._bundlesCfs){
				const http = new HttpRequest();
				http.get(url,(res)=>{
					this._bundlesCfs = res;
					resolve(true);
				},(err)=>{
					console.log("加载配置文件失败",err);
					reject(err);
				});
			}else{
				resolve(true);
			}
			
		});

	}
	private _onFilesProgress(curr: number, total: number) {
		console.log("curr_n",curr,"total_n",total);
	}
	loadBundle(bundlename: string = ""): Promise<AssetManager.Bundle> {
		return new Promise((resolve, reject) => {
			const bundle: AssetManager.Bundle = assetManager.getBundle(bundlename);
			if (!bundle) {
				const option =  this._bundlesCfs? {
					version: this._bundlesCfs.bundles[bundlename],
					onFileProgress:this._onFilesProgress.bind(this)
				}:null;
				assetManager.loadBundle(
					(this._bundlesCfs?.remote||"") + bundlename,
					option,
					(error: Error, b: AssetManager.Bundle) => {
						if (error) {
							reject(error.message);

							return error;
						}
						resolve(b);
					})
			} else {
				resolve(bundle);
			}
		});
	}
	loadAsyncFromBundle<T extends Asset>( bundlename: string = "",path: string, type?:new(...args)=>T): Promise<T> {
		if (bundlename.length < 1) {
			return Promise.reject("bundlename is empty");
		}

		return new Promise(async (resolve, reject) => {
			function loadfunc(bundle: AssetManager.Bundle) {
				const data = bundle.get(path, type);
				if (data) {
					// console.log("no need to load",path)
					resolve(data);
				} else {
					bundle.load(path, type, (error, asset: T) => {
						if (error) {
							reject(error.message);

							return error;
						}
						resolve(asset);
					});
				}
			}
			const bundle: AssetManager.Bundle = await this.loadBundle(bundlename);
			loadfunc(bundle);
		});
	}
}